home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c / 727 < prev    next >
Text File  |  1996-08-06  |  6KB  |  148 lines

  1. Path: newshost.uwo.ca!gateway!mail
  2. From: Dave Kinchlea <kinch@julian.uwo.ca>
  3. Newsgroups: comp.std.c
  4. Subject: offsetof() and `address constant expression': LONG
  5. Date: 12 Apr 1996 00:48:08 GMT
  6. Organization: The University of Western Ontario, London, Ont. Canada
  7. Message-ID: <4kk988$rt2@falcon.ccs.uwo.ca>
  8. NNTP-Posting-Host: julian.uwo.ca
  9. X-Date: Thu, 11 Apr 1996 20:48:07 -0400 (EDT)
  10. Originator: daemon@julian.uwo.ca
  11.  
  12. I think the excellent reply included below from Roger Glover of CRI
  13. (from an original thread in comp.unix.cray) says just about
  14. everything, but for a little more context. I am porting pdksh5.2.4 to
  15. UNICOS and I came across a compiler error that I thought I had
  16. attributed to the following (mis-)defined macro in stddef.h:
  17.  
  18. #if _RELEASE < 3
  19. #define offsetof(t, memb) ((size_t)__INTADDR__(&(((t *)0)->memb)))
  20. #else
  21. #ifndef __cplusplus
  22. #define offsetof(_TYPE, _MEMBER)   _Offsetof(_TYPE, _MEMBER)
  23. #else
  24. #define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0))
  25. #endif
  26. #endif
  27.  
  28. I conjectured that the #ifndef __cplusplus was meant to be #ifdef (the 
  29. compiler version is 4.0), that is the macro that I ended up redefining to 
  30. get the code to compile, and appearently work.
  31.  
  32. Roger makes an excellent case to support the compiler errors, I think 
  33. everything hinges on the exact definition of address constant expression. 
  34. Plauger says:
  35.     An address constant expression specifies a value that has a 
  36.     pointer type and that the translator or target environment can
  37.     determine prior to program startup. Therefore, the epxression must
  38.     not cause side effects. ...
  39.  
  40. Seems pretty clear that the use below does not fit this description but I 
  41. would like some confirmation before I send this back to the author. If it 
  42. matters, that call is out of an alloc() routine. ICELLS is a macro (100) 
  43. and cells is an integer. I think I will let Roger take over ...
  44.  
  45.  On Thu, 11 Apr 1996, Roger Glover wrote:
  46.  
  47.  > Dave:
  48.  > 
  49.  > I took a spare moment to look a this again.  Your code line was:
  50.  > 
  51.  > :>  bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells]));
  52.  > 
  53.  > Your error messages were:
  54.  > 
  55.  > :> cc-544 cc: ERROR File = alloc.c, Line = 92
  56.  > :>   The token "cells" is not valid in a constant expression in this context.
  57.  > :> cc-424 cc: ERROR File = alloc.c, Line = 92
  58.  > :>   The array subscript expression is not a positive integral expression.
  59.  > :> cc-477 cc: ERROR File = alloc.c, Line = 92
  60.  > :>   An expression is terminated with ")" instead of ";".
  61.  > 
  62.  > I used the UNICOS "explain" command to look at these messages in more
  63.  > detail.  Here is what I got for the first message:
  64.  > 
  65.  >     $ explain cc-544
  66.  > 
  67.  >     CC_ERROR:  The token "token" is not valid in a constant expression in this
  68.  >     context.
  69.  > 
  70.  >     The specified token, while valid within some constant expressions, is not
  71.  >     valid within a constant expression used to specify the size of a bit field
  72.  >     member, the value of an enumeration constant, or the value of a case
  73.  >     constant.  Remove the indicated operator from the constant expression.
  74.  > 
  75.  > Not particularly instructive, but the second message cleared things
  76.  > up a bit:
  77.  > 
  78.  >     $ explain cc-424
  79.  > 
  80.  >     CC_ERROR:  The array subscript expression is not a positive integral
  81.  >     expression.
  82.  > 
  83.  >     The expression that specifies the subscript of an array within an offsetof
  84.  >     macro must be an integral constant expression that has a value greater than
  85.  >                               ^^^^^^^^ [[ my emphasis - rg ]]
  86.  >     zero.  Either the subscript specified is not an integral constant expression
  87.  >     or its value is less than or equal to 0.
  88.  > 
  89.  > It clear that the subscript expression (ICELLS + cells) is not
  90.  > constant because the variable "cells" is not constant.  The
  91.  > straightforward macro that you are suggesting is the correct one:
  92.  > 
  93.  >     #define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0))
  94.  > 
  95.  > does not do any integrity checking of the second argument, whereas
  96.  > the one you are suggesting is wrong:
  97.  > 
  98.  >     #define offsetof(_TYPE, _MEMBER)   _Offsetof(_TYPE, _MEMBER)
  99.  >     
  100.  > apparently does perform integrity checking.
  101.  > 
  102.  > The question remains:  Is the integrity check correct?  Well, the fact
  103.  > that the error message is cc-424 (indicating the C compiler rather
  104.  >                           ^^
  105.  > than the C++ compiler) shows me that the integrity check is
  106.  > intentionally associated with C rather than C++.  So I turned to the
  107.  > standards (more or less).  Plauger and Brodie's "Standard C Quick
  108.  > Reference" (ISBN: 1-55615-158-6), which is a concise interpretation
  109.  > of the ANSI/ISO C standard, says the following about the "offsetof"
  110.  > macro:
  111.  >                             offsetof
  112.  >         #define offsetof(s-type,mbr)  <size_t constant expression>
  113.  >     The macro yields the offset in bytes of member mbr from the beginning
  114.  >     of structure type s-type, where for X of type s-type, &X.mbr is an
  115.  >     address constant expression.
  116.  >             ^^^^^^^^
  117.  > 
  118.  > Well let's break that down a bit.  &X.mbr must be constant, so that
  119.  > implies that both X must represent fixed locations and mbr must
  120.  > represent a fixed offset from that location. In your case, mbr is
  121.  > "cell[ICELLS + cells]", which does not represent a fixed offset,
  122.  > since "cells" can vary.
  123.  > 
  124.  > Now one more question remains:  Why doesn't C++ have the same
  125.  > integrity check?  I don't know.  As far as I can tell, the C++ draft
  126.  > standard subsumes stddef.h, "as is" from ANSI/ISO C.  Perhaps their
  127.  > is an implementation dependency related to our C++ compiler, but I
  128.  > can't tell.
  129.  > 
  130.  > In any case, I do not think the behavior you described is a bug.
  131.  > 
  132.  > ----------------------------------------------- Roger Glover
  133.  > XXXX\ \ / \ /XXX  \ / \ X   \ /\\\  X///X /\\\  Cray Research, Inc.
  134.  > / \ / \/ /\ / \ / \X /\ X  \  / \   X\  \ X     DISCLAIMER HAIKU:
  135.  > //X/  X\\\X //X/  X \ X X\\   / \   X/X \ X \\\   C R I may not
  136.  > / \   X///X / \/  X//XX X  \  / \   X  \\ X   \   Share these opinions with me
  137.  > / \   X   X /\\\/ X   X X///X /XXX/ X///X /XXX/   This is not my fault
  138.  > ----------------------------------------------- http://www.cray.com/education
  139.  
  140. kinch  <finger kinch@julian.uwo.ca> for PGP key(s)
  141. email:kinch@julian.uwo.ca    web:http://www.heartlab.rri.uwo.ca/kinch/
  142. Unix PGP Key fingerprint =  6F 36 6F 9D 79 16 DF 40  2B EC 18 5B 5C 6D 03 6F 
  143. Home PGP Key fingerprint =  28 20 0E DF 27 17 80 C5  5D 04 8E 1B D0 9A A6 4C 
  144.  
  145.  
  146.  
  147.  
  148.